/**
 * 
 */
package com.zxc.elasticsearch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpHost;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.action.support.replication.ReplicationResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import com.alibaba.fastjson.JSON;

/**
 * @author admin
 *
 */
public class ElasticsearchDemo1 {

	public static void main(String[] args) throws IOException {
		RestHighLevelClient client = null;
		try {
			client = new RestHighLevelClient(
			        RestClient.builder(new HttpHost("192.168.18.100", 9200, "http")));
			
//			createIndex(client);
//			deleteIndex(client);
			
//			openIndex(client);
			
//			closeIndex(client);
			
//			index(client);
			
//			getIndex(client);

//			delIndex(client);
			
			search(client);
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(client != null){
				client.close();
			}
		}
	}
	
	public static void search(RestHighLevelClient client) throws IOException{
		SearchRequest searchRequest = new SearchRequest(); 
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
		searchSourceBuilder.query(QueryBuilders.matchAllQuery()); 
		searchRequest.source(searchSourceBuilder); 
		
//		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); 
//		sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); 
//		sourceBuilder.from(0); 
//		sourceBuilder.size(5); 
//		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
		
		SearchResponse searchResponse = client.search(searchRequest);
		
		RestStatus status = searchResponse.status();
		TimeValue took = searchResponse.getTook();
		Boolean terminatedEarly = searchResponse.isTerminatedEarly();
		boolean timedOut = searchResponse.isTimedOut();
		
		int totalShards = searchResponse.getTotalShards();
		int successfulShards = searchResponse.getSuccessfulShards();
		int failedShards = searchResponse.getFailedShards();
		for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
		    // failures should be handled here
		}
		
		SearchHits hits = searchResponse.getHits();
		long totalHits = hits.getTotalHits();
		float maxScore = hits.getMaxScore();
		SearchHit[] searchHits = hits.getHits();
		for (SearchHit hit : searchHits) {
		    // do something with the SearchHit
			String index = hit.getIndex();
			String type = hit.getType();
			String id = hit.getId();
			float score = hit.getScore();
			
			String sourceAsString = hit.getSourceAsString();
			
			System.out.println(sourceAsString);
//			Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//			String documentTitle = (String) sourceAsMap.get("title");
//			List<Object> users = (List<Object>) sourceAsMap.get("user");
//			Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject");
			
			
		}
	}
	
	
	public static void delIndex(RestHighLevelClient client) throws IOException{
		DeleteRequest request = new DeleteRequest(
		        "mylog", 
		        "price",  
		        "1");
		
		DeleteResponse deleteResponse = client.delete(request);
		
		String index = deleteResponse.getIndex();
		String type = deleteResponse.getType();
		String id = deleteResponse.getId();
		long version = deleteResponse.getVersion();
		
		System.out.println("index "+index+", type "+type+",id "+id+",version "+version);
		
		ReplicationResponse.ShardInfo shardInfo = deleteResponse.getShardInfo();
		if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
		    
		}
		if (shardInfo.getFailed() > 0) {
		    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
		        String reason = failure.reason(); 
		        System.out.println("failure reason "+reason);
		    }
		}
	}
	
	public static void getIndex(RestHighLevelClient client) throws IOException{
		GetRequest getRequest = new GetRequest(
		        "mylog", 
		        "price",  
		        "1");
		
		GetResponse getResponse = client.get(getRequest);
		
		String index = getResponse.getIndex();
		String type = getResponse.getType();
		String id = getResponse.getId();
		
		System.out.println("index "+ index + ",type "+type+",id "+id);
		if (getResponse.isExists()) {
		    long version = getResponse.getVersion();
		    System.out.println("version "+version);
		    String sourceAsString = getResponse.getSourceAsString();    
		    System.out.println("sourceAsString "+sourceAsString);
		    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap(); 
		    System.out.println("sourceAsMap "+JSON.toJSONString(sourceAsMap));
		    byte[] sourceAsBytes = getResponse.getSourceAsBytes();  
		    System.out.println("sourceAsBytes "+new String(sourceAsBytes));
		    
		} else {
		    System.out.println("not exists");
		}
	}
	
	public static void index(RestHighLevelClient client) throws IOException{
		
		InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("link_path.2018-06-07.0.log");
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
		String tempString = null;  
		int line = 1;  
		// 一次读入一行，直到读入null为文件结束  
		while ((tempString = reader.readLine()) != null) {  
			IndexRequest request = new IndexRequest(
			        "mylog", 
			        "price",  
			        ""+line);   
			String jsonString = tempString;
			request.source(jsonString, XContentType.JSON);
			
			IndexResponse indexRespone = client.index(request);
			
			System.out.println("index:"+indexRespone.getIndex()+",type:"+indexRespone.getType()+",id:"+indexRespone.getId()+",seqno:"+indexRespone.getSeqNo()+",result:"+indexRespone.getResult().name());
			line++;  
		}  

		reader.close();  
		
	}
	
	public static void closeIndex(RestHighLevelClient client) throws IOException{
		CloseIndexRequest request = new CloseIndexRequest("mylog");
		CloseIndexResponse closeIndexResponse = client.indices().close(request);
		System.out.println("acknowledged "+closeIndexResponse.isAcknowledged());
	}
	
	public static void openIndex(RestHighLevelClient client) throws IOException{
		OpenIndexRequest request = new OpenIndexRequest("mylog");
		OpenIndexResponse openIndexResponse = client.indices().open(request);
		
		System.out.println("acknowledged "+openIndexResponse.isAcknowledged());
		System.out.println("shardsAcknowledged "+openIndexResponse.isShardsAcknowledged());
	}
	
	public static void deleteIndex(RestHighLevelClient client) throws IOException{
		try {
			DeleteIndexRequest request = new DeleteIndexRequest("fengxiang");
			DeleteIndexResponse deleteIndexResponse = client.indices().delete(request);
			System.out.println("acknowledged "+deleteIndexResponse.isAcknowledged());
		} catch (ElasticsearchException exception) {
			System.out.println(exception.status().name());
			if (exception.status() == RestStatus.NOT_FOUND) {
				
			}
		}
	}
	
	public static void createIndex(RestHighLevelClient client) throws IOException{
		CreateIndexRequest createIndexRequest = new CreateIndexRequest("fengxiang");
		createIndexRequest.settings(Settings.builder()
			    .put("index.number_of_shards", 3)
			    .put("index.number_of_replicas", 2)
			);
		createIndexRequest.mapping("price", 
				"  {\n" +
					    "    \"price\": {\n" +
					    "      \"properties\": {\n" +
					    "        \"fromCity\": {\n" +
					    "          \"type\": \"text\"\n" +
					    "        }\n" +
					    "      }\n" +
					    "    }\n" +
					    "  }", 
			    XContentType.JSON);
		createIndexRequest.alias(
			    new Alias("mylog_alias")  
			);
		CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest);
		System.out.println("index "+createIndexResponse.index());
		System.out.println("acknowledged "+createIndexResponse.isAcknowledged());
		System.out.println("shardsAcknowledged "+createIndexResponse.isShardsAcknowledged());
	}
}
